﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using SyncLib;
using SyncLib.Interface;
using SyncLib.Client;
using System.Threading;
using System.Windows.Forms;
using log4net;

namespace SyncApplication
{
    public static class WcfClientUtil
    {
        public static string DefaultBindingName = "WSHttpBinding_ISyncManager";
        public static ProxyInfo<T> CreateProxy<T>(string uri, string bindingName)
        {
            WSHttpBinding binding = new WSHttpBinding(bindingName);
            ChannelFactory<T> factory = new ChannelFactory<T>(binding);
            factory.Endpoint.ListenUri = new Uri(uri);
            factory.Endpoint.Address = new EndpointAddress(uri);
            T channel = factory.CreateChannel();
            ProxyInfo<T> temp = new ProxyInfo<T>();
            temp.Ide = new System.Diagnostics.Stopwatch();
            temp.ChannelFactory = factory;
            temp.Channel = channel;
            return temp;
        }

        internal static ProxyInfo<T1> CreateProxy<T1>(string Uri)
        {
            return CreateProxy<T1>(Uri, DefaultBindingName);
        }

        internal static ProxyInfo<T1> CreateProxy<T1>()
        {
            return CreateProxy<T1>(ClientSyncContext.UrlProvider.Url, ClientSyncContext.UrlProvider.BindingName);
        }
    }

    public class WCFConnection : IDisposable
    {
        static ILog Log = LogManager.GetLogger(typeof(Log4NetImplement));
        private bool _IsClose = false;
        private ProxyInfo<ISyncManager> _ProxyInfo;
        private Thread _KeepAliveThread;
        public ProxyInfo<ISyncManager> ProxyInfo { get { return _ProxyInfo; } }


        public void Open()
        {
            if (_ProxyInfo != null)
                InternalDisconnect();

            InternalConnect();

        }
        public void Close()
        {
            InternalDisconnect();
        }

        public void Dispose()
        {

        }
        private void InternalConnect()
        {
            _ProxyInfo = WcfClientUtil.CreateProxy<ISyncManager>(ClientSyncContext.UrlProvider.Url, ClientSyncContext.UrlProvider.BindingName);
            _KeepAliveThread = new Thread(new ThreadStart(delegate()
            {
                try
                {
                    _ProxyInfo.Channel.KeepAlive();

                    
                    while (!_IsClose)
                    {
                        if(_ProxyInfo.Ide.Elapsed.TotalSeconds>20)
                        {
                            Log.Debug("WCFConnection Call KeepAlive");
                            _ProxyInfo.Channel.KeepAlive();
                          
                        }
                        else
                            Log.Debug("WCFConnection Not Call KeepAlive");
                       
                        Thread.Sleep(1000);
                    }
                }
                catch(Exception ex)
                {
                    Log.Fatal("WCFConnection Call KeepAlive Exception:", ex);
                    int i=0;
                    while (i < 10)
                    {
                        Thread.Sleep(100);
                        i++;
                    }
                }

            }));
            _KeepAliveThread.Start();
            while (!_KeepAliveThread.IsAlive)
            {
                Thread.Sleep(100);
                Application.DoEvents();
            }
        }

        private void InternalDisconnect()
        {
            _IsClose = true;
            Log.Debug("InternalDisconnect WCF Client");
            if (_KeepAliveThread != null && _KeepAliveThread.IsAlive == true)
            {
                _KeepAliveThread.Join();
            }
            if (ProxyInfo != null)
            {
                if (ProxyInfo.ChannelFactory.State != System.ServiceModel.CommunicationState.Closed)
                    ProxyInfo.ChannelFactory.Close();
            }
        }
    }
}
